package com.jingdianjichi.wx.handler;

import com.jingdianjichi.wx.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 微信公众号接收到文本消息后的处理器实现
 * 用于处理用户发送给公众号的文本消息，特别是处理包含特定关键词的消息，如"验证码"，
 * 并生成验证码发送给用户。
 *
 * @author: WuYimin
 * @date: 2024-02-10
 */
@Component
@Slf4j
public class ReceiveTextMsgHandlerImpl implements WxChatMsgHandler {

	@Resource
	private RedisUtil redisUtil;

	// 定义接收到的文本消息中需要响应的关键词
	private static final String KEY_WORD = "验证码";

	// 验证码在Redis中的前缀
	private static final String LOGIN_PREFIX = "loginCode";

	/**
	 * 指定处理的消息类型
	 * @return 文本消息类型
	 */
	@Override
	public WxChatMsgTypeEnum getMsgType() {
		return WxChatMsgTypeEnum.TEXT_MSG;
	}

	/**
	 * 处理文本消息的具体逻辑
	 * 当消息内容为"验证码"时，生成一个随机验证码并通过Redis缓存，然后回复用户验证码信息
	 *
	 * @param messageMap 包含微信消息内容的Map
	 * @return 构造的响应消息的XML字符串
	 */
	@Override
	public String dealMsg(Map<String, String> messageMap) {
		log.info("接收到文本消息事件");
		// 获取消息内容
		String content = messageMap.get("Content");
		// 如果消息不是请求验证码，则不处理
		if (!KEY_WORD.equals(content)) {
			return "";
		}
		// 用户的微信号
		String fromUserName = messageMap.get("FromUserName");
		// 公众号的微信号
		String toUserName = messageMap.get("ToUserName");

		// 生成随机验证码
		Random random = new Random();
		int num = random.nextInt(1000);
		// 构造在Redis中存储验证码的键
		String numKey = redisUtil.buildKey(LOGIN_PREFIX, String.valueOf(num));
		// 将验证码存储到Redis中，设置5分钟过期
		redisUtil.setNx(numKey, fromUserName, 5L, TimeUnit.MINUTES);
		// 构造验证码信息内容
		String numContent = "您当前的验证码是：" + num + "！ 5分钟内有效";
		// 构造回复给用户的消息XML格式字符串
		String replyContent = "<xml>\n" +
				"  <ToUserName><![CDATA[" + fromUserName + "]]></ToUserName>\n" +
				"  <FromUserName><![CDATA[" + toUserName + "]]></FromUserName>\n" +
				"  <CreateTime>12345678</CreateTime>\n" +
				"  <MsgType><![CDATA[text]]></MsgType>\n" +
				"  <Content><![CDATA[" + numContent + "]]></Content>\n" +
				"</xml>";

		return replyContent;
	}
}
